{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Linear Regression Example\n",
    "\n",
    "A linear regression learning algorithm example using TensorFlow library.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import numpy\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "import os\n",
    "os.environ[\"CUDA_DEVICE_ORDER\"]='PCI_BUS_ID'\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"]=\"1\"\n",
    "rng = numpy.random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Parameters\n",
    "learning_rate = 0.01\n",
    "training_epochs = 1000\n",
    "display_step = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Training Data\n",
    "train_X = numpy.asarray([3.3,4.4,5.5,6.71,6.93,4.168,9.779,6.182,7.59,2.167,\n",
    "                         7.042,10.791,5.313,7.997,5.654,9.27,3.1])\n",
    "train_Y = numpy.asarray([1.7,2.76,2.09,3.19,1.694,1.573,3.366,2.596,2.53,1.221,\n",
    "                         2.827,3.465,1.65,2.904,2.42,2.94,1.3])\n",
    "n_samples = train_X.shape[0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x7f12504f5650>]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f1250804cd0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#show data\n",
    "plt.plot(train_X, train_Y, 'ro', label='Original data')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Learn a linear regression to fit the dataset\n",
    "y_pred = w*x+b\n",
    "\n",
    "We learn w and b from the dataset"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Two phase to write your tf program\n",
    "### Build a model (assemble a graph)\n",
    "1. Define placeholders for input and output (label)\n",
    "2. Define the weight\n",
    "3. Define the inference model\n",
    "4. Define loss function\n",
    "5. Define optimizer\n",
    "\n",
    "### Training (Use a session to execute operations in the graph)\n",
    "1. Initialize model parameters\n",
    "2. Input training data\n",
    "3. Execute inference model on training data\n",
    "4. Compute loss\n",
    "5. Adust mode parameters to minimize the loss\n",
    "6. Repeat 2->5 util loss convergence\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### linear regression v1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7f12a490bb50>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.placeholder(tf.float32,name='w')\n",
    "    b = tf.placeholder(tf.float32,name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "tf.summary.FileWriter('linear_model_v1',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.001796215 W= 0.377180755138 b= -0.116386435926\n",
      "Epoch: 0100 cost= 0.001373004 W= 0.369592547417 b= -0.0617973804474\n",
      "Epoch: 0150 cost= 0.001026769 W= 0.362455636263 b= -0.0104549890384\n",
      "Epoch: 0200 cost= 0.000746951 W= 0.355743199587 b= 0.0378338359296\n",
      "Epoch: 0250 cost= 0.000524312 W= 0.349429965019 b= 0.0832507014275\n",
      "Epoch: 0300 cost= 0.000350774 W= 0.343492209911 b= 0.125966414809\n",
      "Epoch: 0350 cost= 0.000219277 W= 0.337907612324 b= 0.166141614318\n",
      "Epoch: 0400 cost= 0.000123660 W= 0.332655161619 b= 0.20392742753\n",
      "Epoch: 0450 cost= 0.000058550 W= 0.327715098858 b= 0.239465937018\n",
      "Epoch: 0500 cost= 0.000019269 W= 0.323068827391 b= 0.272890806198\n",
      "Epoch: 0550 cost= 0.000001746 W= 0.318698912859 b= 0.304327726364\n",
      "Epoch: 0600 cost= 0.000002447 W= 0.314588874578 b= 0.333894968033\n",
      "Epoch: 0650 cost= 0.000018303 W= 0.310723304749 b= 0.361703693867\n",
      "Epoch: 0700 cost= 0.000046660 W= 0.307087630033 b= 0.387858510017\n",
      "Epoch: 0750 cost= 0.000085223 W= 0.303668171167 b= 0.412457793951\n",
      "Epoch: 0800 cost= 0.000132012 W= 0.300452083349 b= 0.435594022274\n",
      "Epoch: 0850 cost= 0.000185324 W= 0.297427296638 b= 0.45735424757\n",
      "Epoch: 0900 cost= 0.000243696 W= 0.294582396746 b= 0.477820277214\n",
      "Epoch: 0950 cost= 0.000305879 W= 0.291906684637 b= 0.497069120407\n",
      "Epoch: 1000 cost= 0.000370805 W= 0.28939011693 b= 0.515173137188\n",
      "Optimization Finished, spend time: 11.0523588657!\n",
      "{<tf.Tensor 'params/w:0' shape=<unknown> dtype=float32>: 0.28939011265340536, <tf.Tensor 'params/b:0' shape=<unknown> dtype=float32>: 0.51517313003748655, <tf.Tensor 'inputs/x:0' shape=<unknown> dtype=float32>: array([  3.3  ,   4.4  ,   5.5  ,   6.71 ,   6.93 ,   4.168,   9.779,\n",
      "         6.182,   7.59 ,   2.167,   7.042,  10.791,   5.313,   7.997,\n",
      "         5.654,   9.27 ,   3.1  ]), <tf.Tensor 'inputs/y:0' shape=<unknown> dtype=float32>: array([ 1.7  ,  2.76 ,  2.09 ,  3.19 ,  1.694,  1.573,  3.366,  2.596,\n",
      "        2.53 ,  1.221,  2.827,  3.465,  1.65 ,  2.904,  2.42 ,  2.94 ,  1.3  ])}\n",
      "Training cost= 0.0820096 w= 0.28939011693 b= 0.515173137188 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f12a197f550>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "with tf.Session() as sess:\n",
    "    #initialize the w,b by random\n",
    "    values = {w:rng.randn(),b:rng.randn()}\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np,grad_w_np,grad_b_np = sess.run([cost,grad_w,grad_b], feed_dict=values)\n",
    "            #update the parameters\n",
    "            values[w] -= learning_rate * grad_w_np\n",
    "            values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "    print values\n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## linear regression v2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7f1250457610>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.Variable(rng.randn(),name='w')\n",
    "    b = tf.Variable(rng.randn(),name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "with tf.name_scope('update_params'):\n",
    "    new_w = w.assign(w-learning_rate*grad_w)\n",
    "    new_b = w.assign(b-learning_rate*grad_b)\n",
    "init = tf.global_variables_initializer()\n",
    "tf.summary.FileWriter('linear_model_v2',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "v3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0100 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0150 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0200 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0250 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0300 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0350 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0400 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0450 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0500 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0550 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0600 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0650 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0700 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0750 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0800 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0850 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0900 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 0950 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Epoch: 1000 cost= 0.071842253 W= 0.508991 b= 1.28502\n",
      "Optimization Finished, spend time: 7.58594489098!\n",
      "Training cost= 2.44103 w= 0.508991 b= 1.28502 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f125014b110>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    values = {}\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np = sess.run([cost], feed_dict=values)\n",
    "            #update the parameters\n",
    "            #values[w] -= learning_rate * grad_w_np\n",
    "            #values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "  \n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensor(\"update_params/Assign:0\", shape=(), dtype=float32_ref) Tensor(\"update_params/Assign_1:0\", shape=(), dtype=float32_ref)\n",
      "name: \"update_params/group_deps\"\n",
      "op: \"NoOp\"\n",
      "input: \"^update_params/Assign\"\n",
      "input: \"^update_params/Assign_1\"\n",
      "\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<tensorflow.python.summary.writer.writer.FileWriter at 0x7f125015bb90>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "# define the input by placeholder\n",
    "with tf.name_scope('inputs'):\n",
    "    x = tf.placeholder(tf.float32,name='x')\n",
    "    y = tf.placeholder(tf.float32,name='y')\n",
    "# define the weight\n",
    "# represent the learnable paramters by tf.placeholder\n",
    "with tf.variable_scope('params'):\n",
    "    w = tf.Variable(rng.randn(),name='w')\n",
    "    b = tf.Variable(rng.randn(),name='b')\n",
    "# construct inference model\n",
    "with tf.name_scope('inference'):\n",
    "    y_pred = tf.multiply(w,x) + b\n",
    "# Mean squared error as loss function\n",
    "with tf.name_scope('loss'):\n",
    "    cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "with tf.name_scope('grads'):\n",
    "    grad_w,grad_b = tf.gradients(cost,[w,b])\n",
    "with tf.name_scope('update_params'):\n",
    "    new_w = w.assign(w-learning_rate*grad_w)\n",
    "    new_b = b.assign(b-learning_rate*grad_b)\n",
    "    print new_w,new_b\n",
    "    updates = tf.group(new_w,new_b)\n",
    "    print updates\n",
    "init = tf.global_variables_initializer()\n",
    "tf.summary.FileWriter('linear_model_v2',tf.get_default_graph())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.0055483\n",
      "Epoch: 0050 cost= 0.005548301 W= 0.210726 b= 1.08108\n",
      "0.00530915\n",
      "Epoch: 0100 cost= 0.005309150 W= 0.213037 b= 1.06445\n",
      "0.00508904\n",
      "Epoch: 0150 cost= 0.005089037 W= 0.215211 b= 1.04881\n",
      "0.00488626\n",
      "Epoch: 0200 cost= 0.004886260 W= 0.217256 b= 1.0341\n",
      "0.0046993\n",
      "Epoch: 0250 cost= 0.004699301 W= 0.219179 b= 1.02026\n",
      "0.00452679\n",
      "Epoch: 0300 cost= 0.004526786 W= 0.220988 b= 1.00725\n",
      "0.00436747\n",
      "Epoch: 0350 cost= 0.004367469 W= 0.22269 b= 0.995011\n",
      "0.00422023\n",
      "Epoch: 0400 cost= 0.004220233 W= 0.22429 b= 0.983499\n",
      "0.00408405\n",
      "Epoch: 0450 cost= 0.004084054 W= 0.225795 b= 0.972672\n",
      "0.00395801\n",
      "Epoch: 0500 cost= 0.003958011 W= 0.227211 b= 0.962488\n",
      "0.0038413\n",
      "Epoch: 0550 cost= 0.003841298 W= 0.228542 b= 0.952913\n",
      "0.00373312\n",
      "Epoch: 0600 cost= 0.003733117 W= 0.229793 b= 0.943907\n",
      "0.00363279\n",
      "Epoch: 0650 cost= 0.003632791 W= 0.230971 b= 0.935437\n",
      "0.00353967\n",
      "Epoch: 0700 cost= 0.003539667 W= 0.232078 b= 0.92747\n",
      "0.00345319\n",
      "Epoch: 0750 cost= 0.003453186 W= 0.23312 b= 0.919978\n",
      "0.00337283\n",
      "Epoch: 0800 cost= 0.003372825 W= 0.234099 b= 0.91293\n",
      "0.00329811\n",
      "Epoch: 0850 cost= 0.003298106 W= 0.235021 b= 0.906302\n",
      "0.00322859\n",
      "Epoch: 0900 cost= 0.003228594 W= 0.235887 b= 0.900068\n",
      "0.00316388\n",
      "Epoch: 0950 cost= 0.003163884 W= 0.236702 b= 0.894204\n",
      "0.00310362\n",
      "Epoch: 1000 cost= 0.003103620 W= 0.237469 b= 0.888689\n",
      "Optimization Finished, spend time: 9.24333190918!\n",
      "Training cost= 0.0774802 w= 0.237469 b= 0.888689 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f124c03db10>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# compute\n",
    "# Start training\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    sess.run(init)\n",
    "    # Fit all training data\n",
    "    t_start = time.time()\n",
    "    values = {}\n",
    "    for epoch in range(training_epochs):\n",
    "        for (X, Y) in zip(train_X, train_Y):\n",
    "            values[x] = X\n",
    "            values[y] = Y\n",
    "            #compute the gradients\n",
    "            cost_np,_ = sess.run([cost,updates], feed_dict=values)\n",
    "            #print(w_np,b_np)\n",
    "            #print cost_np\n",
    "            #update the parameters\n",
    "            #values[w] -= learning_rate * grad_w_np\n",
    "            #values[b] -= learning_rate * grad_b_np\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        #print (epoch+1) % display_step\n",
    "        #print values\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c = sess.run(cost, feed_dict=values)\n",
    "            print(c)\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(w), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    values[x] = train_X\n",
    "    values[y] = train_Y\n",
    "  \n",
    "    training_cost = sess.run(cost, feed_dict=values)\n",
    "    print \"Training cost=\", training_cost, \"w=\", sess.run(w,feed_dict=values), \"b=\", sess.run(b,feed_dict=values), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(w,feed_dict=values) * train_X + sess.run(b,feed_dict=values), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "tf.reset_default_graph()\n",
    "# tf Graph Input\n",
    "X = tf.placeholder(\"float\")\n",
    "Y = tf.placeholder(\"float\")\n",
    "\n",
    "# Set model weights\n",
    "W = tf.Variable(rng.randn(), name=\"weight\")\n",
    "b = tf.Variable(rng.randn(), name=\"bias\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Construct a linear model\n",
    "pred = tf.add(tf.multiply(X, W), b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "17\n"
     ]
    }
   ],
   "source": [
    "# Mean squared error\n",
    "cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2.*n_samples)\n",
    "print n_samples\n",
    "#cost = tf.reduce_sum(tf.pow(y_pred-y, 2))/(2*n_samples)\n",
    "# Gradient descent\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Initialize the variables (i.e. assign their default value)\n",
    "init = tf.global_variables_initializer()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 0050 cost= 0.079245120 W= 0.277222 b= 0.609393\n",
      "Epoch: 0100 cost= 0.078977935 W= 0.275593 b= 0.621037\n",
      "Epoch: 0150 cost= 0.078742325 W= 0.274062 b= 0.631974\n",
      "Epoch: 0200 cost= 0.078534484 W= 0.272625 b= 0.642249\n",
      "Epoch: 0250 cost= 0.078351215 W= 0.271274 b= 0.651901\n",
      "Epoch: 0300 cost= 0.078189649 W= 0.270006 b= 0.660967\n",
      "Epoch: 0350 cost= 0.078047112 W= 0.268814 b= 0.669485\n",
      "Epoch: 0400 cost= 0.077921450 W= 0.267694 b= 0.677487\n",
      "Epoch: 0450 cost= 0.077810638 W= 0.266642 b= 0.685003\n",
      "Epoch: 0500 cost= 0.077712923 W= 0.265654 b= 0.692063\n",
      "Epoch: 0550 cost= 0.077626802 W= 0.264726 b= 0.698696\n",
      "Epoch: 0600 cost= 0.077550873 W= 0.263854 b= 0.704927\n",
      "Epoch: 0650 cost= 0.077483937 W= 0.263035 b= 0.710781\n",
      "Epoch: 0700 cost= 0.077424921 W= 0.262266 b= 0.716279\n",
      "Epoch: 0750 cost= 0.077372931 W= 0.261543 b= 0.721446\n",
      "Epoch: 0800 cost= 0.077327058 W= 0.260864 b= 0.726299\n",
      "Epoch: 0850 cost= 0.077286676 W= 0.260226 b= 0.730858\n",
      "Epoch: 0900 cost= 0.077251084 W= 0.259627 b= 0.73514\n",
      "Epoch: 0950 cost= 0.077219732 W= 0.259064 b= 0.739163\n",
      "Epoch: 1000 cost= 0.077192098 W= 0.258535 b= 0.742941\n",
      "Optimization Finished, spend time: 8.76383304596!\n",
      "Training cost= 0.0771423 W= 0.258535 b= 0.742941 \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f129c313310>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Start training\n",
    "with tf.Session() as sess:\n",
    "    t_start = time.time()\n",
    "    sess.run(init)\n",
    "\n",
    "    # Fit all training data\n",
    "    for epoch in range(training_epochs):\n",
    "        for (x, y) in zip(train_X, train_Y):\n",
    "            #print x\n",
    "            sess.run(optimizer, feed_dict={X: x, Y: y})\n",
    "\n",
    "        #Display logs per epoch step\n",
    "        if (epoch+1) % display_step == 0:\n",
    "            c,_ = sess.run([cost,optimizer], feed_dict={X: train_X, Y:train_Y})\n",
    "            print \"Epoch:\", '%04d' % (epoch+1), \"cost=\", \"{:.9f}\".format(c), \\\n",
    "                \"W=\", sess.run(W), \"b=\", sess.run(b)\n",
    "\n",
    "    print \"Optimization Finished, spend time: {}!\".format(time.time()-t_start)\n",
    "    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})\n",
    "    print \"Training cost=\", training_cost, \"W=\", sess.run(W), \"b=\", sess.run(b), '\\n'\n",
    "\n",
    "    #Graphic display\n",
    "    plt.plot(train_X, train_Y, 'ro', label='Original data')\n",
    "    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')\n",
    "    plt.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Regression result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
